
package API_itextpdf;

import com.adobe.acrobat.Viewer;
import com.itextpdf.awt.DefaultFontMapper;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import gui.Anexo;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import metodologia.ConjuntoDeEtapas;
import metodologia.DadosMetodologia;
import metodologia.Etapa;
import metodologia.Teste;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.data.category.DefaultCategoryDataset;

/**
 * Gerencia o arquivo PDF gerado como relatorio
 * 
 * @author PW-UFRN
 */
public class ManagerPDF implements java.io.Serializable {

    private DadosMetodologia dados;
    
    public static final Font BOLD10;
    public static final Font BOLD12;
    public static final Font BOLD14;
    public static final Font BOLD20;
    public static final Font BOLD22;
    public static final Font NORMAL10;
    public static final Font NORMAL12;
    public static final Font White12;

    static {
        BaseFont timesbd = null;
        BaseFont times = null;
        try {
            timesbd = BaseFont.createFont("c:/windows/fonts/timesbd.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED);
            times = BaseFont.createFont("c:/windows/fonts/times.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED);
        } catch (DocumentException e) {
            e.printStackTrace();
            System.exit(1);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }

        BOLD10 = new Font(timesbd, 10);
        BOLD12 = new Font(timesbd, 12);
        BOLD14 = new Font(timesbd, 14);
        BOLD20 = new Font(timesbd, 20);
        BOLD22 = new Font(timesbd, 22);
        NORMAL10 = new Font(times, 10);
        NORMAL12 = new Font(times, 12);
        White12 = new Font(times, 12,0, BaseColor.WHITE);
    }    
    public void createPdf(DadosMetodologia dadosMetodologia, int nTests, ArrayList<String[]> execucao, 
            ArrayList<String[]> exec, ArrayList<Anexo> dadosAnexo, String filename) throws DocumentException, IOException {

        this.dados = dadosMetodologia;
        
        Document document = new Document(PageSize.A4);
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
        
        //Cabeçalho
        TableHeader event = new TableHeader();
        writer.setPageEvent(event);
        
        document.open();
        
        DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
        Date date = new Date();
        String dataString = dateFormat.format(date);
        
        /** Definindo um cabeçalho vazio para a capa */
        headerDocument(event, true);
        
        /** Capa (Load existing PDF) */
        PdfContentByte cb = writer.getDirectContent();
        PdfReader reader = new PdfReader("/ImageFiles/capa.pdf");
        PdfImportedPage page = writer.getImportedPage(reader, 1);
        document.newPage();
        cb.addTemplate(page, 0, 0);
        document.newPage();
        
        /** Sumário */
        document.newPage();
        
        /** Definindo um cabeçalho para a capa */
        headerDocument(event, false);
        
        /** Prefácio */
        addPreface(document, dataString);
        
        /**
         * Informações sobre Metodologia
         */ 
        document.newPage();
        
        document.add(new Paragraph(dados.getNome(), new Font(BOLD20)));
        // Aqui: Descrição da metodologia
        document.add(new Paragraph("\tExecução:", BOLD20));
        
        convertToPdf(getBarChart(execucao,nTests),480,250,filename,document,writer);

        int x = 1;
        int numeroDoTesteNaDescricao = 1;
        for (Iterator it = exec.iterator(); it.hasNext();) {
            String[] dado = (String[]) it.next();

            if (x <= Integer.parseInt(dado[0])) {
                document.add(new Paragraph("    Teste " + numeroDoTesteNaDescricao + ": " + dado[3], BOLD14));
                document.add(new Paragraph("        " + dado[4]));
                x = (Integer.parseInt(dado[0]) + 1);
                numeroDoTesteNaDescricao++;
            }
            if (dado[1] == null) {
                dado[1] = "0";
            }
            if (Integer.parseInt(dado[1]) != 0) {
                document.add(new Paragraph("            Conjunto de Etapas " + dado[1] + ": ", BOLD14));
                writeSteps(document, Integer.parseInt(dado[1]), dado[2]);
                
                if (!(dado[6] == null || dado[6].equals(""))) {
                    Phrase phrase = new Phrase("                Observações: ", BOLD14);
                    Phrase phrase1 = new Phrase(dado[6], NORMAL12);
                    document.add(phrase);
                    document.add(phrase1);
                }
            }
            
            
        }

        document.newPage();
        
        /** Conclusao e Referencias */
        addConclusion(document);
        
        /** ANEXO */        
//////////        boolean haveTable = false;
//////////        ArrayList<String> nTest = new ArrayList<>();
//////////        ArrayList<String> nConjStep = new ArrayList<>();
//////////        ArrayList<String> nStep = new ArrayList<>();
//////////        ArrayList<PdfPTable> nTable = new ArrayList<>();
//////////       
//////////        //Percorre todos os conj.etapas
//////////        
//////////        for(int i=0; i<dados.getProgress().size(); i++){
//////////           
//////////            //Percorre todos os checkboxs do progress escolhido
//////////            for (int j=0; j<dados.getProgress().get(i).getCheckBox().length; j++){
//////////                //Verifica se existe modificação ou a tabela continua null               
//////////                if (dados.getProgress().get(i).getActive().get(j)){
////////////                    if (dados.getProgress().get(i).getTitleTable().get(j).size() > 0) {
//////////                    
//////////                        //Se for a primeira tabela a ser incerida entao adicione o titulo do anexo
//////////                        if (haveTable == false) {
//////////                            Paragraph aux_p = new Paragraph("ANEXO", BOLD22);
//////////                            aux_p.setAlignment(Paragraph.ALIGN_CENTER);
//////////                            document.add(aux_p);        
//////////                            document.add(new Paragraph(" "));        
//////////                            document.add(new Paragraph("1. Tabela de Dados", BOLD20));
//////////
//////////                            haveTable = true;
//////////                        }
//////////    //                    System.out.println("Conj Etapas: " + i + " ----- checkboxs: " + j);
//////////    //                    
//////////    //                    document.add(new Paragraph(" "));
//////////    //                    document.add(new Paragraph("    Teste " + (dados.getProgress().get(i).getTestId()) + ": ", BOLD14));
//////////    //                    document.add(new Paragraph("          Conjunto de Etapas " + (dados.getProgress().get(i).getStepId()-1) + ": ", BOLD14));
//////////    //                    document.add(new Paragraph("                  Etapa " + (j+1) + ": ", BOLD12));
//////////
//////////                        PdfPTable table;
//////////                        
//////////                        int numberCol = 0;
//////////                        for(int y =0; y<dados.getProgress().get(i).getTableItens().get(j).size(); y++){
//////////                            if (numberCol < dados.getProgress().get(i).getTableItens().get(j).get(y).size()){
//////////                                numberCol = dados.getProgress().get(i).getTableItens().get(j).get(y).size();
//////////                            }
//////////                        }
//////////                        if (dados.getProgress().get(i).getTitleTable().get(j).size() >= numberCol){
//////////                            table = new PdfPTable(dados.getProgress().get(i).getTitleTable().get(j).size());
//////////                        } else{
//////////                            table = new PdfPTable(numberCol);
//////////                        }
//////////
//////////                        //Adiciona os titulos da tabela
//////////                        //table.addCell(header);
//////////                        if (!dados.getProgress().get(i).getTitleTable().get(j).isEmpty()){
//////////                            for(int p=0; p<dados.getProgress().get(i).getTitleTable().get(j).size(); p++){
//////////                                //adiciona os titulos da tabela em cor branca com fundo preto para destacar os titulos do resto da tabela
//////////                                PdfPCell cell = new PdfPCell (new Paragraph (dados.getProgress().get(i).getTitleTable().get(j).get(p), White12));
//////////                                cell.setBackgroundColor(BaseColor.BLACK);
//////////
//////////                                table.addCell(cell);
//////////                            }
//////////                        } else{
//////////                            for(int p=0; p<numberCol; p++){
//////////                                //adiciona os titulos da tabela em cor branca com fundo preto para destacar os titulos do resto da tabela
//////////                                PdfPCell cell = new PdfPCell (new Paragraph (" ", White12));
//////////                                cell.setBackgroundColor(BaseColor.BLACK);
//////////
//////////                                table.addCell(cell);
//////////                            }
//////////                        }
//////////
//////////                        //Adiciona os dados da tabela
//////////                        for (int u=0; u<dados.getProgress().get(i).getTableItens().get(j).size(); u++){
//////////                            for (int l=0; l<dados.getProgress().get(i).getTableItens().get(j).get(u).size(); l++){
//////////                                if (dados.getProgress().get(i).getTableItens().get(j).get(u).get(l).equals("")){
//////////                                    table.addCell(" ");                               
//////////                                } else{
//////////                                    table.addCell(dados.getProgress().get(i).getTableItens().get(j).get(u).get(l));
//////////                                }
//////////                            }
//////////                        }
//////////
//////////                        // Adicionando as Listas
//////////                        String teste = "";
//////////                        String conjEtapa = "";
//////////                        String etapa = "";
//////////
//////////                        if((dados.getProgress().get(i).getTestId() >= 0) && (dados.getProgress().get(i).getTestId() < 10)){
//////////                            teste = "00000" + String.valueOf(dados.getProgress().get(i).getTestId());
//////////                        }else if ((dados.getProgress().get(i).getTestId() > 9) && (dados.getProgress().get(i).getTestId() < 100)){
//////////                            teste = "0000" + String.valueOf(dados.getProgress().get(i).getTestId());
//////////                        }else if ((dados.getProgress().get(i).getTestId() > 99) && (dados.getProgress().get(i).getTestId() < 1000)){
//////////                            teste = "000" + String.valueOf(dados.getProgress().get(i).getTestId());
//////////                        }else if ((dados.getProgress().get(i).getTestId() > 999) && (dados.getProgress().get(i).getTestId() < 10000)){
//////////                            teste = "00" + String.valueOf(dados.getProgress().get(i).getTestId());
//////////                        }else if ((dados.getProgress().get(i).getTestId() > 9999) && (dados.getProgress().get(i).getTestId() < 100000)){
//////////                            teste = "0" + String.valueOf(dados.getProgress().get(i).getTestId());
//////////                        }
//////////
//////////                        if((dados.getProgress().get(i).getStepId() >= 0) && (dados.getProgress().get(i).getStepId() < 10)){
//////////                            conjEtapa = "00000" + String.valueOf(dados.getProgress().get(i).getStepId()-1);
//////////                        }else if ((dados.getProgress().get(i).getStepId() > 9) && (dados.getProgress().get(i).getStepId() < 100)){
//////////                            conjEtapa = "0000" + String.valueOf(dados.getProgress().get(i).getStepId()-1);
//////////                        }else if ((dados.getProgress().get(i).getStepId() > 99) && (dados.getProgress().get(i).getStepId() < 1000)){
//////////                            conjEtapa = "000" + String.valueOf(dados.getProgress().get(i).getStepId()-1);
//////////                        }else if ((dados.getProgress().get(i).getStepId() > 999) && (dados.getProgress().get(i).getStepId() < 10000)){
//////////                            conjEtapa = "00" + String.valueOf(dados.getProgress().get(i).getStepId()-1);
//////////                        }else if ((dados.getProgress().get(i).getStepId() > 9999) && (dados.getProgress().get(i).getStepId() < 100000)){
//////////                            conjEtapa = "0" + String.valueOf(dados.getProgress().get(i).getStepId()-1);
//////////                        }
//////////
//////////                        if((j+1 >= 0) && (j+1 < 10)){
//////////                            etapa = "00000" + String.valueOf(j+1);
//////////                        }else if ((j+1 > 9) && (j+1 < 100)){
//////////                            etapa = "0000" + String.valueOf(j+1);
//////////                        }else if ((j+1 > 99) && (j+1 < 1000)){
//////////                            etapa = "000" + String.valueOf(j+1);
//////////                        }else if ((j+1 > 999) && (j+1 < 10000)){
//////////                            etapa = "00" + String.valueOf(j+1);
//////////                        }else if ((j+1 > 9999) && (j+1 < 100000)){
//////////                            etapa = "0" + String.valueOf(j+1);
//////////                        }
//////////
//////////                        nTest.add(teste);
//////////                        nConjStep.add(teste + "-" + conjEtapa);
//////////                        nTable.add(table);
//////////                        nStep.add(teste + "-" + conjEtapa 
//////////                                + "-" + etapa + "&" + nTable.indexOf(table));
//////////                                      
////////////                    //Adiciona ao documento.
////////////                    document.add(new Paragraph(" "));
////////////                    document.add(table);                    
////////////                    }
//////////                }
//////////            }
//////////        }
//////////        
//////////        // Ordenação de listas
//////////        if (haveTable){
//////////            if ((nTest.size() == nConjStep.size()) && (nTest.size() == nStep.size())){
//////////                ArrayList<ArrayList<String>> list = new ArrayList<>();
//////////                list.add(nTest);
//////////                list.add(nConjStep);
//////////                list.add(nStep);
//////////
//////////                for(int x1 = 0; x1<list.size(); x1++){
//////////                    Collections.sort(list.get(x1));
//////////                }
//////////                Collections.sort(list, new Comparator<ArrayList<String>>(){
//////////
//////////                    @Override
//////////                    public int compare(ArrayList<String> t1, ArrayList<String> t2) {
//////////                        return t1.get(0).compareTo(t2.get(0));
//////////                    }
//////////
//////////                });
//////////            } else {
//////////                System.out.println("[Erro_Ordenação das tabelas do anexo] Listas com tamanhos diferentes");
//////////            }
//////////
//////////            ArrayList<Integer> nTableId = new ArrayList<>();
//////////            ArrayList<PdfPTable> nTableNew = new ArrayList<>();
//////////
//////////            //Retirando os Infes da ordenação
//////////            for(int x1=0; x1<nTest.size(); x1++){
//////////                String[] n = nTest.get(x1).toString().split("-");
//////////                String[] n1 = nConjStep.get(x1).toString().split("-");
//////////                String[] n2 = nStep.get(x1).toString().split("-");
//////////
//////////                String[] n2_aux = n2[n2.length-1].split("&");
//////////
//////////                nTest.set(x1, n[n.length-1]);
//////////                nConjStep.set(x1, n1[n1.length-1]);
//////////                nStep.set(x1, n2_aux[0]);
//////////                nTableNew.add(nTable.get(Integer.valueOf(n2_aux[1])));
//////////            }
//////////
//////////            //Adicionando as Tabelas ordenadas no relatorio
//////////            for (int h = 0; h<nTest.size(); h++) {
//////////
////////////                document.add(new Paragraph(" "));
////////////                document.add(new Paragraph("    Teste " + Integer.valueOf(nTest.get(h)) + ": ", BOLD14));
////////////                document.add(new Paragraph("          Conjunto de Etapas " + Integer.valueOf(nConjStep.get(h)) + ": ", BOLD14));
////////////                document.add(new Paragraph("                  Etapa " + Integer.valueOf(nStep.get(h)) + ": ", BOLD12));
////////////                document.add(new Paragraph(" "));
////////////                document.add(nTableNew.get(h));
//////////                
//////////                // ou mudar tudo q ta dentro do for para:
//////////                String titulo = "Erro";
//////////                
//////////                for (Iterator it = exec.iterator(); it.hasNext();) {
//////////                    String[] dado = (String[]) it.next();
//////////                        
//////////                    if(Integer.valueOf(nTest.get(h)) == Integer.parseInt(dado[0])) {
//////////                        titulo = dado[3];
//////////                    }
//////////                }
//////////                document.add(new Paragraph(" "));
//////////                document.add(new Paragraph("    Teste: " + titulo, BOLD14));
//////////                document.add(new Paragraph("          Conjunto de Etapas " + (Integer.valueOf(nConjStep.get(h))+1) + ": ", BOLD14));
//////////                document.add(new Paragraph("                  Etapa " + Integer.valueOf(nStep.get(h)) + ": ", BOLD12));
//////////                document.add(new Paragraph(" "));
//////////                document.add(nTableNew.get(h));
//////////            }
//////////        } else{
//////////            //Não tem tabela para ordenar!
//////////        }
        
        /** ANEXO */
        
        // Armazena todos os elementos do anexo que serão colocados no "document" caso tenha alguma tabela no anexo.
        ArrayList<Element> documentAux = new ArrayList<>(); 
        
        boolean haveTable = false;
        // Verifica se tem alguma tabela completada
        boolean tableCompleteAll = false;
        
        for (int i = 0; i<dadosAnexo.size(); i++) {
            
            if ((dadosAnexo.get(i).getTable() != null) && (!dadosAnexo.get(i).getTable().isEmpty())) {
                
                if (haveTable == false) {
                    Paragraph aux_p = new Paragraph("ANEXO", BOLD22);
                    aux_p.setAlignment(Paragraph.ALIGN_CENTER);
                    documentAux.add(aux_p);        
                    documentAux.add(new Paragraph(" "));        
                    documentAux.add(new Paragraph("1. Tabela de Dados", BOLD20));

                    haveTable = true;
                }
                
                // Cria a tabela
                PdfPTable table; 
                // Inicializa a tabela com a quantidade de titulos
                table = new PdfPTable(dadosAnexo.get(i).getTable().get(0).size()); 
                
                //Adiciona os titulos da tabela (em cor branca com fundo preto para destacar os titulos do resto da tabela)
                if ((!dadosAnexo.get(i).getTitulosTabela().isEmpty()) && (dadosAnexo.get(i).getTitulosTabela() != null)){
                    for (int j = 0; j<dadosAnexo.get(i).getTitulosTabela().size() ;j++) {
                        PdfPCell cell = new PdfPCell (new Paragraph (dadosAnexo.get(i).getTitulosTabela().get(j), White12));
                        cell.setBackgroundColor(BaseColor.BLACK);

                        table.addCell(cell);
                    }
                } else {
                    for (int j = 0; j<dadosAnexo.get(i).getTable().get(0).size() ;j++) {
                        PdfPCell cell = new PdfPCell (new Paragraph (" ", White12));
                        cell.setBackgroundColor(BaseColor.BLACK);

                        table.addCell(cell);
                    }
                }
                
                // Verifica no final se a tabela foi completada ou está vazia
                boolean tableComplete = false;
                
                //Adiciona os dados da tabela
                for (Iterator it2 = dadosAnexo.get(i).getTable().iterator(); it2.hasNext();) {
                    ArrayList<String> linha = (ArrayList<String>) it2.next();
                    
                    for (Iterator it3 = linha.iterator(); it3.hasNext();) {
                        String coluna = (String) it3.next();
                        
                        if ((!coluna.equals("")) && (coluna != null)){
                            table.addCell(coluna);
                            tableComplete = true;
                            tableCompleteAll = true;
                        }
                    }
                }
//                Adiciona os dados da tabela
//                for (int u=0; u<dados.getProgress().get(i).getTableItens().get(j).size(); u++){
//                    for (int l=0; l<dados.getProgress().get(i).getTableItens().get(j).get(u).size(); l++){
//                        if (dados.getProgress().get(i).getTableItens().get(j).get(u).get(l).equals("")){
//                            table.addCell(" ");                               
//                        } else{
//                            table.addCell(dados.getProgress().get(i).getTableItens().get(j).get(u).get(l));
//                        }
//                    }
//                }
                
                if(tableComplete){
                    documentAux.add(new Paragraph(" "));
                    documentAux.add(new Paragraph("    Teste " + dadosAnexo.get(i).getNTeste() + ": " + dadosAnexo.get(i).getNomeTeste(), BOLD14));
                    documentAux.add(new Paragraph("          Conjunto de Etapas " + dadosAnexo.get(i).getNConjEtapa() + ": ", BOLD14));
                    documentAux.add(new Paragraph("                  Etapa: " + dadosAnexo.get(i).getNomeEtapa(), BOLD12));
                    documentAux.add(new Paragraph(" "));
                    documentAux.add(table);
                }
            }
        }
        
        if(tableCompleteAll){
            for(int g=0; g< documentAux.size(); g++){
                document.add(documentAux.get(g));
            } 
        }
        
        document.close();

        /**
         * Visualizando relatorio
         */
        //showPdf(filename);
        
        System.out.println("** Relatório gerado com sucesso! **");
    }

    /**
     * Organiza o cabeçalho do documento
     * @param event
     * @param document
     * @param dados
     * @throws DocumentException 
     * 
     */
    private void headerDocument(TableHeader event, boolean aux) throws DocumentException {

        event.setHeader("Metodologia para Instalação de instrumentos wireless", aux);

    }
    
    /**
     * Metodo que escreve as etapas e suas marcações
     * 
     * @param document
     * @param catId_conj
     * @param dado
     * @param dados
     * @throws DocumentException
     * @throws BadElementException
     * @throws MalformedURLException
     * @throws IOException 
     */
    private void writeSteps(Document document, int catId_conj, String dado) 
            throws DocumentException, BadElementException, MalformedURLException, IOException {
        
        String nome = "";
        String descricao = "";
        String[] aux_split = dado.toString().split(" - ");
        ArrayList<String> aux_check = new ArrayList<>();
        ArrayList<String> aux_name = new ArrayList<>();
        ArrayList<String> aux_desc = new ArrayList<>();
        
        for (int s = 0; s<aux_split.length; s++){
            String[] z;
            z = aux_split[s].split("#");
            if(z.length == 3){
                aux_check.add(z[2]);
                aux_desc.add(z[1]);
                aux_name.add(z[0]);
            }else{
                System.out.println("Erro no split do dado em WRITESTEPS");
            }
        }
       
        java.awt.Image image1 = ImageIO.read(getClass().getResourceAsStream("/ImageFiles/27-15x15.png"));
        java.awt.Image image2 = ImageIO.read(getClass().getResourceAsStream("/ImageFiles/23-15x15.png"));
        Image  imageD = Image.getInstance(image1, null);
        Image  imageM = Image.getInstance(image2, null);
      
//        //Percorre os testes
//        for (int i = 0; i<dados.getListaDeTestes().size(); i++){
//            //Percorre os conjuntos de tarefas/etapas
//            for (int j = 0; j<dados.getListaDeTestes().get(i).getListaDoConjuntoDasEtapas().size(); j++){
//                //Percorre as tarefas/etapas
//                 for (int k = 0; k<dados.getListaDeTestes().get(i).getListaDoConjuntoDasEtapas().get(j).getListaDeEtapa().size(); k++){
//                    //Verifica se o conjunto de etapas é o mesmo que solicitado pelo catId.
//                    if (dados.getListaDeTestes().get(i).getListaDoConjuntoDasEtapas().get(j).getCatid() == catId_conj){
                        
                        for(int u=0; u<aux_name.size(); u++){
//                            if(aux_name.get(u).equals(dados.getListaDeTestes().get(i).getListaDoConjuntoDasEtapas().get(j).getListaDeEtapa().get(k).getTitulo())){

//                                nome = dados.getListaDeTestes().get(i).getListaDoConjuntoDasEtapas().get(j).getListaDeEtapa().get(k).getTitulo();
//                                descricao = dados.getListaDeTestes().get(i).getListaDoConjuntoDasEtapas().get(j).getListaDeEtapa().get(k).getDescricao();
                                
                                nome = aux_name.get(u);
                                descricao = aux_desc.get(u);
                                
                                PdfPTable tabela = new PdfPTable(4); //cria uma tabela com 4 colunas
                                tabela.setWidths(new int[]{1, 7, 17, 1});

                                Paragraph p0 = new Paragraph((u+1) + "-");
                                PdfPCell celula0 = new PdfPCell(p0);

                                Paragraph p1 = new Paragraph(nome);
                                PdfPCell celula1 = new PdfPCell(p1); 

                                Paragraph p2 = new Paragraph(descricao);
                                PdfPCell celula2 = new PdfPCell(p2);

                                PdfPCell celula3 = new PdfPCell(imageD); //Default é desmarcado
                                if (aux_check.get(u).equals("1")) {
                                    //adicione quadrado marcado                         
                                    celula3 = new PdfPCell(imageM);
                                    celula3.setHorizontalAlignment(Element.ALIGN_RIGHT);
                                }else if (aux_check.get(u).equals("0")) {
                                    //adicione quadrado desmarcado                                                 
                                    celula3 = new PdfPCell(imageD);
                                    celula3.setHorizontalAlignment(Element.ALIGN_RIGHT);
                                }

                                celula0.setBorder(-1); // aqui vc tira as bordas da celula   
                                celula1.setBorder(-1);    
                                celula2.setBorder(-1);  
                                celula3.setBorder(-1);

                                tabela.addCell(celula0); //aqui adiciona as celulas na tabela.
                                tabela.addCell(celula1);   
                                tabela.addCell(celula2);  
                                tabela.addCell(celula3); 

                                document.add(tabela); // coloca a tabela na pagina do PDF.

//                            }//if
                        }//for aux_name

//                    }//if
//                }//k
//            }//j
//        }//i

    } 
    
    /**
     * Metodo que retorna o grafico de execução
     * 
     * @param execucao 0:nº do teste; 1:nº da etapa; 2:% concluida; 3:quantidade de check box marcado; 4:qnt maxima de checkbox cada etapa;
     * @param nTests
     * @return
     * @throws IOException 
     */
    public JFreeChart getBarChart(ArrayList<String[]> execucao, int nTests) throws IOException{
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        
        /*
         * Execução
         */
        float checkboxs;
        float checked;
        int numeroDoTesteNoGrafico = 1;
        int nTesteAnterior = 0;
        for (Iterator it = execucao.iterator(); it.hasNext();) {
            String[] dado = (String[]) it.next();
            
            checkboxs = 0;
            checked = 0;
            for (Iterator it2 = execucao.iterator(); it2.hasNext();) {
                String[] dado2 = (String[]) it2.next();

                if(dado[0].equals(dado2[0]) && (dado2[3] != null || dado2[4] != null)) {
                    checked += Float.parseFloat(dado2[3]);
                    checkboxs += Float.parseFloat(dado2[4]);
                }
            }
            
            if (numeroDoTesteNoGrafico == 1 && nTesteAnterior == 0){ // if e else para atualizar o numero do teste no grafico
                nTesteAnterior = Integer.parseInt(dado[0]);
            } else if (nTesteAnterior < Integer.parseInt(dado[0])) {
                numeroDoTesteNoGrafico++;
                nTesteAnterior = Integer.parseInt(dado[0]);
            }
            
            dataset.setValue((checked*100)/checkboxs, "Concluido(%)", Integer.toString(numeroDoTesteNoGrafico));
        }
        
        
//        int x = 1;
//        float c = 0; // quantidade total de checkbox marcados na metodologia
//        float d = 0; // quantidade total de checkbox da metodologia
//        for (Iterator it = execucao.iterator(); it.hasNext();) {
//            String[] dado = (String[]) it.next();
//            
//            for (Iterator it2 = execucao.iterator(); it2.hasNext();) {
//                String[] dado2 = (String[]) it2.next();
//                
//                if (x == Integer.parseInt(dado2[0]) && (dado2[3] != null || dado2[4] != null)) {
//                    c = c + Float.parseFloat(dado2[3]);
//                    d = d + Float.parseFloat(dado2[4]);
//                }
//            }
//            
//            if (x == Integer.parseInt(dado[0])) {
//                dataset.setValue((c*100)/d, "Concluido(%)", dado[0]);
//                x++;
//            }
//            c =0;
//            d = 0;
//        }
        
        JFreeChart chart = ChartFactory.createBarChart("Gráfico de Execução","Testes",
                "Concluido(%)", dataset, PlotOrientation.VERTICAL, false,true,false);
        
        
        CategoryPlot categoryPlot = chart.getCategoryPlot();
        CategoryItemRenderer renderer = categoryPlot.getRenderer();
        categoryPlot.getRangeAxis().setRange(0, 100);
        renderer.setSeriesPaint( 0, Color.BLUE );
        BarRenderer br = (BarRenderer) categoryPlot.getRenderer();
        br.setMaximumBarWidth(.08);
        
        return chart;
    }
    
    /**
     * Converte o grafico em imagem para pdf.
     * 
     * @param chart
     * @param width
     * @param height
     * @param filename
     * @param document
     * @param writer 
     * 
     */
    public void convertToPdf (JFreeChart chart, int width, int height, String filename, Document document, PdfWriter writer) {
        try {
            PdfContentByte cb = writer.getDirectContent();
            PdfTemplate tp = cb.createTemplate(width, height);
            Graphics2D g2d = tp.createGraphics(width, height,new DefaultFontMapper());
            Rectangle2D r2d = new Rectangle2D.Double(0,0,width,height);
            chart.draw(g2d,r2d);
            g2d.dispose();
            cb.addTemplate(tp,25,490);
            
            //Pulando linhas para alocar o grafico
            for (int a = 0; a<16; a++) {
                document.add(new Paragraph(" "));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

        
    /**
     * Método que mostra o arquivo pdf gerado
     * 
     * @param filename 
     */
    private void showPdf(String filename){

        int response;
        
        response = JOptionPane.showConfirmDialog(null, "Deseja abrir o relatório gerado?", "Aviso", JOptionPane.YES_NO_OPTION);
                
        if (response == JOptionPane.YES_OPTION){
            InputStream input;
            Viewer viewer;  
            JFrame frame = new JFrame("Visualização do Relatório: "+ filename);  
            frame.setLayout(new BorderLayout());
            try{  
                viewer = new Viewer();  
                frame.add(viewer, BorderLayout.CENTER);  
                input = new FileInputStream (new File(filename));

                if(input != null){  
                    ByteArrayOutputStream output = new ByteArrayOutputStream();  
                    // set read buffer size  
                    byte[] rb = new byte[1024];  
                    int ch = 0;  
                    while ((ch = input.read(rb)) != -1){  
                        output.write(rb, 0, ch);  
                    }
                    byte[] b = output.toByteArray();  
                    input.close();  
                    output.close();  
                    viewer.setDocumentInputStream(new ByteArrayInputStream(b));  
                }
                viewer.activate();  
                viewer.setProperty("Default_Page_Layout", "SinglePage");  
                viewer.setProperty("Default_Zoom_Type", "FitVisibleWidth");  
                viewer.setProperty("Default_Magnification", "100");  

                frame.setSize(800, 600);  
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);  
                frame.setVisible(true);  
            }  
            catch(Exception e){  
                JOptionPane.showMessageDialog(null,  
                            "Não foi possível  abrir o arquivo!",  
                            "Erro", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    
    /**
     * Adiciona o prefacio do documento
     * @param document
     * @throws DocumentException 
     */
    private void addPreface(Document document, String dataString) throws DocumentException{
        
        document.add(new Paragraph("Prefácio", new Font(BOLD20)));
        
        Phrase phrase0 = new Phrase("                      O  referido  documento  tem  sido  criado  pelo  grupo  de  pesquisa  do  projeto  ",NORMAL12);
        Phrase phrase1 = new Phrase("Avaliação  de  Desempenho das Redes de Instrumentação Sem-fio (ProjWireless) ",BOLD12);
        Phrase phrase2 = new Phrase("em parceria direta com a ",NORMAL12);
        Phrase phrase3 = new Phrase(" Petrobras-Cenpes ",BOLD12);
        Phrase phrase4 = new Phrase("com  o  objetivo  de  dar  suporte  na  instalação  e  no  comissionamento  "
                + "de  instrumentos  wireless. Entende-se  por  instrumento  wireless  todo aquele dispositivo com "
                + "suporte aos padrões  WirelessHART  ou  ISA100.11a.",NORMAL12);
        document.add(phrase0);
        document.add(phrase1);
        document.add(phrase2);
        document.add(phrase3);
        document.add(phrase4);

        Paragraph paragraph1 = new Paragraph("              O documento assume que o leitor tem conhecimentos mínimos sobre redes industriais "
                + "sem fio e os padrões WirelessHART e ISA100.11a. Detalhes sobre essas tecnologias são encontradas " 
                + "em [1] [2] [3].", new Font(NORMAL12));
        Paragraph paragraph2 = new Paragraph("              A lista completa de fornecedores dos instrumentos WirelessHART e ISA100.11a, até "
                + "o momento da escrita desse documento, é a seguinte:", new Font(NORMAL12));
        Paragraph paragraph3 = new Paragraph("              "/*Ponto*/ + "WirelessHART: Emerson, Siemens, ABB, Endress + Hauser e Pepperl + Fuchs.", new Font(NORMAL12));
        Paragraph paragraph4 = new Paragraph("              "/*Ponto*/ + "ISA100.11a: Honeywell e Yokogawa.", new Font(NORMAL12));
        paragraph1.setAlignment(Paragraph.ALIGN_JUSTIFIED);
        paragraph2.setAlignment(Paragraph.ALIGN_JUSTIFIED);
        paragraph3.setAlignment(Paragraph.ALIGN_JUSTIFIED);
        paragraph4.setAlignment(Paragraph.ALIGN_JUSTIFIED);
        document.add(paragraph1);
        document.add(paragraph2);
        document.add(paragraph3);
        document.add(paragraph4);
        document.add(new Paragraph(" "));
        
        //Historico de Revisoes
        document.add(new Paragraph("Histórico de Revisões", new Font(BOLD20)));
        document.add(new Paragraph(" "));

        PdfPTable table0 = new PdfPTable(4);
        table0.setWidths(new int[]{5, 33, 9, 10});
        table0.setTotalWidth(527);
        table0.setLockedWidth(true);
        PdfPCell cell0 = new PdfPCell (new Paragraph ("Versão", White12));
        cell0.setHorizontalAlignment (Element.ALIGN_CENTER);
        cell0.setBackgroundColor(BaseColor.BLACK);
        PdfPCell cell1 = new PdfPCell (new Paragraph ("Autores", White12));
        cell1.setHorizontalAlignment (Element.ALIGN_CENTER);
        cell1.setBackgroundColor(BaseColor.BLACK);
        PdfPCell cell2 = new PdfPCell (new Paragraph ("Data da Criação", White12));
        cell2.setHorizontalAlignment (Element.ALIGN_CENTER);
        cell2.setBackgroundColor(BaseColor.BLACK);
        PdfPCell cell3 = new PdfPCell (new Paragraph ("Data da Execução", White12));
        cell3.setHorizontalAlignment (Element.ALIGN_CENTER);
        cell3.setBackgroundColor(BaseColor.BLACK);
        table0.addCell(cell0);
        table0.addCell(cell1);
        table0.addCell(cell2);
        table0.addCell(cell3);
        
        PdfPCell cell4 = new PdfPCell (new Paragraph (dados.getVersao(), NORMAL12)); // versao da metodologia
        cell4.setHorizontalAlignment (Element.ALIGN_CENTER);
        table0.addCell(cell4);
        
        table0.addCell(new Paragraph(dados.getAutor(),NORMAL12)); // autor da metodologia
        
        PdfPCell cell5 = new PdfPCell (new Paragraph (" ", NORMAL12)); // data da criação da metodologia
        cell5.setHorizontalAlignment (Element.ALIGN_CENTER);
        table0.addCell(cell5);
        
        PdfPCell cell6 = new PdfPCell (new Paragraph (dataString, NORMAL12)); // data da execução da metodologia
        cell6.setHorizontalAlignment (Element.ALIGN_CENTER);
        table0.addCell(cell6);
        
        table0.addCell(dataString); // data da execução da metodologia
        table0.getDefaultCell().setHorizontalAlignment(Element.ALIGN_MIDDLE);

        document.add(table0);
        document.add(new Paragraph(" "));
        
        //Sugestoes
        document.add(new Paragraph("Sugestões", new Font(BOLD20)));
        Paragraph paragraph5 = new Paragraph("              Envie suas sugestões, dúvidas e outras requisições para a nossa equipe através "
                + "do e-mail contato@projwireless-ufrn.com.", new Font(NORMAL12));
        paragraph5.setAlignment(Paragraph.ALIGN_JUSTIFIED);
        document.add(paragraph5);
        
    }
    
    /**
     * Adiciona as conclusão e Referências do documento
     * @param document
     * @throws DocumentException 
     */
    private void addConclusion(Document document) throws DocumentException{
    
        document.add(new Paragraph("Conclusão", new Font(BOLD20)));        
        document.add(new Paragraph(" "));
        
        Paragraph paragraph6 = new Paragraph("              O desenvolvimento desta metodologia para instalação "
                + "de equipamentos wireless deverá abordar diversos pontos teóricos (envolvendo as normas)"
                + " e práticos (envolvendo as instalações dos equipamentos em plantas reais). "
                + "Para que este documento possa ser uma referência a ser utilizada tanto em fases "
                + "de projeto quanto de instalação é necessário que todos que fazem parte deste projeto "
                + "direta ou indiretamente sigam esta metodologia, informando dados tão precisos quanto "
                + "possíveis e contribuindo com informações não contempladas nos testes, mas que foram "
                + "presenciadas durante a execução deles.",new Font(NORMAL12));

        paragraph6.setAlignment(Paragraph.ALIGN_JUSTIFIED_ALL);
        document.add(paragraph6);        
        document.add(new Paragraph(" "));        
        document.add(new Paragraph("Referências", new Font(BOLD20)));        
        document.add(new Paragraph(" "));

        Phrase phrase5 = new Phrase("1. WILLIG, A. Recent and Emerging Topics in Wireless Industrial Communications: A Selection. ",new Font(NORMAL10));
        Phrase phrase6 = new Phrase("IEEE Transaction on                    Industrial Informatics", new Font(BOLD10));
        Phrase phrase7 = new Phrase(", v. 4, n. 2, p. 102-124, 2008. \n",new Font(NORMAL10));
        
        Phrase phrase8 = new Phrase("2. PETERSEN, S.; CARLSEN, S. WirelessHart Versus ISA100.11a: The Format War Hits the Factory Floor. ", new Font(NORMAL10));
        Phrase phrase9 = new Phrase("IEEE Industrial           Electronics Magazine",new Font(BOLD10));
        Phrase phrase10 = new Phrase(", v. 5, n. 4, p. 23-34, 2011. \n", new Font (NORMAL10));
        
        Phrase phrase11 = new Phrase("3. CHEN, D.; NIXON, M.; MOK, A. ", new Font(NORMAL10));
        Phrase phrase12 = new Phrase("WirelessHART: ", new Font(BOLD10));
        Phrase phrase13 = new Phrase("Real-Time Mesh Network for Industrial Automation. [S.l.]: Incorporated         Springer Publishing Company, 2010.", new Font(NORMAL10));
        
        document.add(phrase5);
        document.add(phrase6);
        document.add(phrase7);
        document.add(phrase8);
        document.add(phrase9);
        document.add(phrase10);
        document.add(phrase11);
        document.add(phrase12);
        document.add(phrase13);
        
        document.newPage();
        
    }
}
